﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

using System.Threading;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
public class UdpServer : MonoBehaviour
{
    public int _point = 60000;
    Thread _thread = null;

    private Socket newsock;//定义一个socket变量
    IPEndPoint ip;//定义一个IP地址和端口号
    int recv;//定义一个接受值的变量
    byte[] data;//定义一个二进制的数组用来获取客户端发过来的数据包

    List<string> _dataList;

    void Start() {
        Loom.Initialize();
        _dataList = new List<string>();

        _labelStyle = new GUIStyle();
        Screen.SetResolution(960, 640, false);
        

        //得到本机IP，设置TCP端口号        
        ip = new IPEndPoint(IPAddress.Any, _point);//设置自身的IP和端口号，在这里IPAddress.Any是自动获取本机IP
        newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);//实例化socket对象设置寻址方案为internetwork（IP版本的4存放）,设置Soket的类型，为Dgram（支持数据报形式的数据），设置协议的类型，为UDP
        newsock.SendTimeout = 5000;
        newsock.ReceiveTimeout = 5000;

        //绑定网络地址
        newsock.Bind(ip);//绑定IP
        Debug.Log("This is a Server,host name is " + Dns.GetHostName());//输出本地的名字
        Debug.Log("Waiting for a client");
        //BeginReceives();
        _thread = new Thread(BeginListening);//定义一个子线程
        _thread.Start();//子线程开始   
    }

    void BeginListening() {
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);//实例化一个网络端点，设置为IPAddress.Any为自动获取跟我通讯的IP，0代表所有的地址都可以
        EndPoint Remote = (EndPoint)(sender);//实例化一个地址结束点来标识网络路径
        //  Debug.Log(Encoding.ASCII.GetString(data, 0, recv));//输出二进制转换为string类型用来测试
        while (true) {
            if (newsock.Available == 0) {
                System.Threading.Thread.Sleep(200);
                continue;
            }

            int bufferSize = newsock.Available;
            if(bufferSize > 3000){
                bufferSize *= 3;
            }
            //Debug.Log("buff size " + bufferSize);
            data = new byte[25000];
            recv = newsock.ReceiveFrom(data, ref Remote);//将数据包接收到的数据放入缓存点，并存储终节点
            //Debug.Log(Encoding.ASCII.GetString(data, 0, recv));
            string str = "IP：" + Remote.ToString() + "    时间：" + DateTime.Now.ToLongTimeString().ToString() + "\n" + Encoding.Default.GetString(data, 0, recv);
            Loom.QueueOnMainThread(() => {
                _dataList.Add(str);
            }); 
            // newsock.SendTo(Encoding.ASCII.GetBytes(mydata),mydata.Length,SocketFlags.None,Remote);

        }
    }

    void SendMessage(string message) {
        byte[] data = new byte[1024];
        Debug.Log("This is a client,host name is" + Dns.GetHostName());
        //IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);//实例化一个网络端点，设置为IPAddress.Any为自动获取跟我通讯的IP，0代表所有的地址都可以
        EndPoint Remote = (EndPoint)(ip);//实例化一个地址结束点来标识网络路径
        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        //string welcome = "你好";
        //data = Encoding.ASCII.GetBytes(welcome);
        ip = new IPEndPoint(IPAddress.Parse("192.168.1.120"), 12346);
        // server.SendTo(data, data.Length, SocketFlags.None, ip);
        // data = new byte[1024];
        server.SendTo(Encoding.ASCII.GetBytes(message), ip);
        // data = new byte[1024];
        Debug.Log("Stopping Client.");
        server.Close();
    }

    Vector2 startScrollPos = Vector2.zero;
    float buttonHight = 30.0f;
    GUIStyle _labelStyle;
    void OnGUI() {

        GUILayout.BeginHorizontal();
        GUILayout.Label("端口号", GUILayout.Width(40), GUILayout.Height(buttonHight));
        _point = int.Parse(GUILayout.TextField(_point.ToString(), GUILayout.Width(60), GUILayout.Height(buttonHight)));

        if (GUILayout.Button("监听", GUILayout.Height(buttonHight))) {
            StopListening();

            //得到本机IP，设置TCP端口号        
            ip = new IPEndPoint(IPAddress.Any, _point);//设置自身的IP和端口号，在这里IPAddress.Any是自动获取本机IP
            newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);//实例化socket对象设置寻址方案为internetwork（IP版本的4存放）,设置Soket的类型，为Dgram（支持数据报形式的数据），设置协议的类型，为UDP

            //绑定网络地址
            newsock.Bind(ip);//绑定IP

            Debug.Log("This is a Server,host name is " + Dns.GetHostName());//输出本地的名字
            Debug.Log("Waiting for a client");
            //BeginReceives();

            _thread = new Thread(BeginListening);
            _thread.Start();
        }

        if (GUILayout.Button("停止", GUILayout.Height(buttonHight))) {
            StopListening();
        }

        if (GUILayout.Button("清理", GUILayout.Height(buttonHight))) {
            _dataList.Clear();
        }

        if (GUILayout.Button("Count " + _dataList.Count, GUILayout.Height(buttonHight), GUILayout.Width(140))) {
        }

        GUILayout.EndHorizontal();

        GUILayout.Space(10);

        startScrollPos = GUILayout.BeginScrollView(startScrollPos, GUILayout.Width(Screen.width), GUILayout.Height(Screen.height - 2 * buttonHight));
        //labelStyle.fontSize = 20;
        for (int i = _dataList.Count; i > 0; i--) {
            //Color lableColor = 
            string str = _dataList[i - 1];
            if (str == "" || str == null || str.Length < 1)
                continue;

            if (str.Contains("Debug:LogError(Object)")) {
                _labelStyle.normal.textColor = Color.red;
            } else if (str.Contains("Debug:LogWarning(Object)")) {
                _labelStyle.normal.textColor = Color.yellow;
            } else {
                _labelStyle.normal.textColor = Color.white;
            }
            GUILayout.Label(str, _labelStyle);
        }

        //foreach (string data in _dataList) {
        //    GUILayout.Label(data);
        //}
        GUILayout.EndScrollView();
    }

    void OnApplicationQuit() {
        StopListening();
    }

    void StopListening() {
        _dataList.Clear();

        if (_thread != null) {
            _thread.Abort();
        }
        if (newsock != null)
            newsock.Close();
    }
}
